package com.chiga.support;

import java.io.File;
import java.io.FileFilter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GeneratorSupport {
	
	private static String MODEL_PATH = "com/opteron/model";
	private static String MODEL_PACKAGE = "com.opteron.model";
	private static String DAO_PACKAGE = "com.opteron.dao";
	private static String SERVICE_PACKAGE = "com.opteron.service";
	private static String ACTION_PACKAGE = "com.opteron.action";
	
	public static List<String> listModel() {
		String url = GeneratorSupport.class.getClassLoader().getResource(MODEL_PATH).getPath();
		try {
			url = URLDecoder.decode(url, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		File baseDir = new File(url);
		
		File[] dirs = baseDir.listFiles();
		List<String> list = new ArrayList<String>();
		for(File dir:dirs) {
			if(dir.isDirectory()) {
				File[] files = dir.listFiles(new FileFilter() {
					@Override
					public boolean accept(File f) {
						if(f.getName().endsWith(".class")) {
							return true;
						}
						return false;
					}
				});
				for(File file:files) {
					String name = dir.getName()+"."+file.getName().replaceAll(".class", "");
					list.add(MODEL_PACKAGE + "." + name);
				}
			}
		}
	
		return list;
		
	}
	
	public static Map<String, String> generateDao(String className) throws ClassNotFoundException {
		Class.forName(className);
		Map<String, String> map = new HashMap<String, String>();
		
		StringBuffer _interface = new StringBuffer();
		StringBuffer _implement = new StringBuffer();
		
		String pkgName = className.substring(0, className.lastIndexOf("."));
		String lastPkgName = pkgName.substring(pkgName.lastIndexOf(".")+1);
		String clazz = className.substring(className.lastIndexOf(".")+1);
		
		map.put("interfacePackage", DAO_PACKAGE + "." +lastPkgName);
		map.put("interfaceName", clazz+"Dao");
		_interface.append("package ").append(DAO_PACKAGE).append(".").append(lastPkgName).append(";")
				.append("\n\n")
				.append("import com.chiga.dao.GenericDao;")
				.append("\n")
				.append("import ").append(className).append(";")
				.append("\n\n")
				.append("public interface ").append(clazz).append("Dao extends GenericDao<").append(clazz).append(", Long> {")
				.append("\n\n")
				.append("}");
		map.put("interfaceContent", _interface.toString());
		
		map.put("implementPackage", DAO_PACKAGE + "." + lastPkgName + ".impl");
		map.put("implementName", clazz + "DaoImpl");
		_implement.append("package ").append(DAO_PACKAGE).append(".").append(lastPkgName).append(".impl;")
				.append("\n\n")
				.append("import org.springframework.stereotype.Repository;")
				.append("\n\n")
				.append("import ").append(DAO_PACKAGE).append(".").append(lastPkgName).append(".").append(clazz).append("Dao;")
				.append("\n")
				.append("import com.chiga.dao.impl.AbstractDao;")
				.append("\n")
				.append("import ").append(className).append(";")
				.append("\n\n")
				.append("@Repository")
				.append("\n")
				.append("public class ").append(clazz).append("DaoImpl extends AbstractDao<").append(clazz).append(", Long>")
				.append(" implements ").append(map.get("interfaceName")).append(" {")
				.append("\n\n")
				.append("\t").append("public ").append(clazz).append("DaoImpl() {")
				.append("\n")
				.append("\t\tsuper(").append(clazz).append(".class);")
				.append("\n")
				.append("\t}")
				.append("\n")
				.append("}");
		map.put("implementContent", _implement.toString());
		
		return map;
	}
	
//	public static void generateDao2File(String className) {
//		Map<String, String> map = generateDao(className);
//		URL url = GeneratorSupport.class.getResource("struts.xml");
//		System.out.println(url.toString());
//	}
	
	public static Map<String, String> generateService(String className) throws ClassNotFoundException {
		Class.forName(className);
		Map<String, String> map = new HashMap<String, String>();
		
		StringBuffer _interface = new StringBuffer();
		StringBuffer _implement = new StringBuffer();
		
		String pkgName = className.substring(0, className.lastIndexOf("."));
		String lastPkgName = pkgName.substring(pkgName.lastIndexOf(".")+1);
		String clazz = className.substring(className.lastIndexOf(".")+1);
		
		map.put("interfacePackage", SERVICE_PACKAGE + "." + lastPkgName);
		map.put("interfaceName", clazz+"Service");
		
		_interface.append("package ").append(SERVICE_PACKAGE).append(".").append(lastPkgName).append(";")
				.append("\n\n")
				.append("import ").append(className).append(";")
				.append("\n")
				.append("import com.chiga.service.GenericService;")
				.append("\n\n")
				.append("public interface ").append(clazz).append("Service extends GenericService<").append(clazz).append(", Long> {")
				.append("\n\n")
				.append("}");
		map.put("interfaceContent", _interface.toString());
		
		
		map.put("implementPackage", SERVICE_PACKAGE + "." + lastPkgName + ".impl");
		map.put("implementName", clazz+"ServiceImpl");
		_implement.append("package ").append(SERVICE_PACKAGE).append(".").append(lastPkgName).append(".impl;")
				.append("\n\n")
				.append("import org.springframework.beans.factory.annotation.Autowired;")
				.append("\n")
				.append("import org.springframework.stereotype.Service;")
				.append("\n\n")
				.append("import ").append(DAO_PACKAGE).append(".").append(lastPkgName).append(".").append(clazz).append("Dao;")
				.append("\n")
				.append("import ").append(className).append(";")
				.append("\n")
				.append("import ").append(SERVICE_PACKAGE).append(".").append(lastPkgName).append(".").append(clazz).append("Service;")
				.append("\n")
				.append("import com.chiga.service.impl.AbstractService;")
				.append("\n\n")
				.append("@Service")
				.append("\n")
				.append("public class ").append(clazz).append("ServiceImpl extends AbstractService<").append(clazz).append(", Long>")
				.append(" implements ").append(map.get("interfaceName")).append(" {")
				.append("\n\n")
				.append("\t@Autowired")
				.append("\n")
				.append("\tpublic ").append(clazz).append("ServiceImpl(").append(clazz).append("Dao ")
				.append(clazz.substring(0,1).toLowerCase()).append(clazz.substring(1)).append("Dao) {")
				.append("\n")
				.append("\t\tsuper(").append(clazz.substring(0,1).toLowerCase()).append(clazz.substring(1)).append("Dao);")
				.append("\n")
				.append("\t}")
				.append("\n")
				.append("}");
		map.put("implementContent", _implement.toString());
		
		return map;
	}
	
	public static Map<String, String> generateAction(String className) throws ClassNotFoundException {
		Class.forName(className);
		Map<String, String> map = new HashMap<String, String>();
		String pkgName = className.substring(0, className.lastIndexOf("."));
		String lastPkgName = pkgName.substring(pkgName.lastIndexOf(".")+1);
		String clazz = className.substring(className.lastIndexOf(".")+1);
		String object = clazz.substring(0, 1).toLowerCase()+clazz.substring(1);
		
		map.put("actionPackage", ACTION_PACKAGE + "." + lastPkgName);
		map.put("actionName", clazz + "Action");
		
		StringBuffer content = new StringBuffer();
		content.append("package ").append(ACTION_PACKAGE).append(".").append(lastPkgName).append(";").append("\n")
			.append("\n")
			.append("import org.springframework.beans.factory.annotation.Autowired;").append("\n")
			.append("import org.springframework.stereotype.Controller;").append("\n")
			.append("\n")
			.append("import com.chiga.action.AbstractPagedAction;").append("\n")
			.append("import com.chiga.dao.support.PagedQueryConfig;").append("\n")
			.append("import com.chiga.message.Message;").append("\n")
			.append("\n")
			.append("import ").append(className).append(";").append("\n")
			.append("import ").append(SERVICE_PACKAGE).append(".").append(lastPkgName).append(".").append(clazz).append("Service;").append("\n")
			.append("\n")
			.append("@Controller").append("\n")
			.append("public class ").append(clazz).append("Action extends AbstractPagedAction {").append("\n")
			.append("\n")
			.append("\t@Autowired").append("\n")
			.append("\tprivate ").append(clazz).append("Service ").append(object).append("Service;").append("\n")
			.append("\n")
			.append("\tprivate ").append(clazz).append(" ").append(object).append(";").append("\n")
			.append("\tprivate PagedQueryConfig queryConfig = this.getQueryConfig(").append(clazz).append(".class);").append("\n")
			.append("\n")
			.append("\tpublic ").append(clazz).append(" get").append(clazz).append("() {").append("\n")
			.append("\t\treturn this.").append(object).append(";").append("\n")
			.append("\t}").append("\n")
			.append("\n")
			.append("\tpublic void set").append(clazz).append("(").append(clazz).append(" ").append(object).append(") {").append("\n")
			.append("\t\tthis.").append(object).append(" = ").append(object).append(";").append("\n")
			.append("\t}").append("\n")
			.append("\n")
			////////query
			.append("\t@Override").append("\n")
			.append("\tpublic String query() {").append("\n")
			.append("\t\ttry {").append("\n")
			.append("\t\t\tthis.processQueryParameter(queryConfig);").append("\n")
			.append("\t\t\tthis.setPageData(").append(object).append("Service.pagedQuery(queryConfig));").append("\n")
			.append("\t\t} catch(Exception e) {").append("\n")
			.append("\t\t\treturn this.error(Message.SELECT_FAIL, e);").append("\n")
			.append("\t\t}").append("\n")
			.append("\t\treturn SUCCESS;").append("\n")
			.append("\t}").append("\n")
			.append("\n")
			////////add
			.append("\t@Override").append("\n")
			.append("\tpublic String add() {").append("\n")
			.append("\t\ttry {").append("\n")
			.append("\t\t\tthis.pushData(\"DATA\",").append(object).append("Service.save(").append(object).append("));").append("\n")
			.append("\t\t\treturn this.info(Message.INSERT_SUCCESS);").append("\n")
			.append("\t\t} catch(Exception e) {").append("\n")
			.append("\t\t\treturn this.error(Message.INSERT_FAIL, e);").append("\n")
			.append("\t\t}").append("\n")
			.append("\t}").append("\n")
			.append("\n")
			////////save
			.append("\t@Override").append("\n")
			.append("\tpublic String save() {").append("\n")
			.append("\t\ttry {").append("\n")
			.append("\t\t\tthis.pushData(\"DATA\",").append(object).append("Service.save(").append(object).append(", false));").append("\n")
			.append("\t\t\treturn this.info(Message.UPDATE_SUCCESS);").append("\n")
			.append("\t\t} catch(Exception e) {").append("\n")
			.append("\t\t\treturn this.error(Message.UPDATE_FAIL, e);").append("\n")
			.append("\t\t}").append("\n")
			.append("\t}").append("\n")
			.append("\n")
			////////delete
			.append("\t@Override").append("\n")
			.append("\tpublic String delete() {").append("\n")
			.append("\t\ttry {").append("\n")
			.append("\t\t\t").append(object).append("Service.deleteAll(ids);").append("\n")
			.append("\t\t\treturn this.info(Message.DELETE_SUCCESS);").append("\n")
			.append("\t\t} catch(Exception e) {").append("\n")
			.append("\t\t\treturn this.error(Message.DELETE_FAIL, e);").append("\n")
			.append("\t\t}").append("\n")
			.append("\t}").append("\n")
			.append("\n")
			.append("}");
		
		map.put("actionContent", content.toString());
		
		return map;
	}
	
	public static void main(String... arg) {
		try{
			Map<String, String> map = generateDao("gov.tpc.model.info.UserInfo");
			System.out.println(map.get("interfaceContent"));
			System.out.println(map.get("implementContent"));
			
			map = generateService("gov.tpc.model.info.UserInfo");
			System.out.println(map.get("interfaceContent"));
			System.out.println(map.get("implementContent"));
			
			map = generateAction("gov.tpc.model.info.UserInfo");
			System.out.println(map.get("actionContent"));

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
